definition module japi
import StdEnv

:: *JapiState 

// ABREVIATIONS
:: *JS :== *JapiState
:: D :== Device
:: F :== Framer         // main Frame
:: C :== Container      // Device Container
:: TD :== TDev          // Text Device
:: E :== Entry          // Menu Entry 
:: CP :== Canvas        // Canvas or Printer 
:: P :== (!Int, !Int)
:: Pair :== (!Real, !Real)

/* The type system has been designed so that
   the compiler can discover whether a function
   can be applyed to its argument. For instance,
   one can apply setText only to TDev arguments;
   the reason is that only TDev devices have 
   text (TDev stands for Devices with Text).
   Clean compiler signals an error if one tries
   to change a property absent in a given device.
   
   Properties associated with each type:
   
   Framer and Container --- have text, size, and position, 
                            and can contain other devices.
   Bar --- can contain menus.
   Menu --- has text, and can contain Entries
   Entry --- has text
   Canvas --- one can draw on a Canvas device, which
              has size, and position, although resizing
              or changing the position of printer has
              no meaning at all.
   LDev --- contains a list of options.
   Device --- usually represents objects that has
              not pictorial representation. Devices
              have no text, no size, and no position
              (exept for S7, that has size and position).
              Examples of Device: mouse, keyboard,
              a seven segment display, and an action.
   TDev --- have text, size, and position.
   
   The advantage of this type system over the previous
   one is that Clean compiler can catch errors at compile
   time, while  languages like C, and Java, that use the
   same type for all devices, produce run time errors.

*/

:: Framer 
:: Container 
:: Bar
:: Menu
:: Entry
:: Canvas
:: LDev
:: Device
:: TDev
:: RC
:: Scroll

:: Pos =    WH !Int !Int | XY !Int !Int 
          | XYWH !Int !Int !Int !Int | FLOW

:: Projection = X | Y

// Named colors can be used to change the
// background color of a non drawable devices,
// like labels, buttons, frames, and fields.
J_BLACK :== 0
J_WHITE :== 1
J_RED   :== 2
J_GREEN :== 3
J_BLUE  :== 4
J_CYAN  :== 5
J_MAGENTA :== 6
J_YELLOW  :== 7

J_ARROW :== 0
J_CROSSHAIR :== 1
J_TEXT   :== 2
J_WAIT :== 3
J_HAND  :== 12
J_MOVE  :== 13



// Drawable describes drawing elements like
// lines, images, texts, rectangles, etc.  

// Img --- image; Txt --- Text; Rct --- Rectangle
// Cir --- circle; Lin --- Line segment
// Arc --- arc of an oval; Ovl --- oval
// Rrc --- Round rectangle
       
// Ovl, Cir, Ar are given by a circumscribing rectangle.
// Rrc (round rectangle) is given by its position, its
// width and height, and the size of its round corners.
// (x,y) give the position;
// w and h gives the width and height of a rectangle.
//

:: Drawable =    
    Img !(!Int,!Int) !Int         // Image_pointer x y
  | Txt !(!Int, !Int) !String     // String x y 
  | Rct !(!Int, !Int) !Int !Int   // (x,y) w h
  | Cir !(!Int, !Int) !Int        // (x,y) radius
  | Lin !(!Int, !Int)(!Int, !Int) // (x1,y1) (x2,y2)
  | Arc !(!Int,!Int) !Int !Int    // (x,y) w h 
        !Int !Int                 // starting_angle endind_angle  
  | Ovl !(!Int,!Int) !Int !Int    // (x,y) w h 
  | Rrc !(!Int,!Int) !Int !Int    // (x,y) w h
        !Int !Int                 // corner_width corner_height
  | Hue !(!Int, !Int, !Int)     // color, i.e., hue
  | Fnt !Font
  | Tri !(!Int, !Int) !(!Int, !Int) !(!Int, !Int)
  | Arr !(!Int, !Int) !(!Int, !Int)
  | Plg ![(Int, Int)] 
  | Pll ![(Int, Int)]
  | Xor !Bool

::CFig = 
     Image !(!Real, !Real) !Int 
   | Text !(!Real, !Real) !String  
   | Rectangle !(!Real, !Real) !Real !Real
   | Circle !(Real, !Real) !Real  
   | Line !(!Real, !Real) !(!Real, !Real) 
   | OvalArc !(!Real, !Real) !Real !Real !Int !Int 
   | Oval !(!Real, !Real) !Real !Real 
   | Arrow !(!Real, !Real) !(!Real, !Real)
   | Axis  
   | Pix !(!Real, !Real)
   | Polygon ![(!Real, !Real)]
   | Polyline ![(!Real, !Real)]
   | Color !(!Int, !Int, !Int) 
   | Background !(!Int, !Int, !Int) 
   | SetFnt !Font
   | SetXor !Bool
   
         
:: Font = Courier !Int | TimesNew !Int | Helvetia !Int

// Function classes

class Show f where
   jshow :: !f !JapiState -> (!f,!JapiState) 
   
instance Show Container
instance Show Framer



class Focus f where
	jsetfocus :: !f !JapiState -> (!f, !*JapiState)
	     
instance Focus Canvas 
instance Focus TDev

class Keyboard f where
   jkeyboard :: !f -> (!Device, !f)
   
instance Keyboard Canvas 
instance Keyboard Framer


class ListBox f where
  jnewLB :: !Pos !Int ![String] !f  !JapiState -> (!LDev, !*JapiState)  

instance ListBox Framer 
instance ListBox Container


class GetImage f where
   jgetimage :: !f -> Int
   
instance GetImage Canvas
instance GetImage RC 

class CutImage f g where
   jcutimage :: !f !(!g, !g) !g !g -> Int
   
instance CutImage Canvas Int 
instance CutImage RC Real


class NewCanvas f where  
	jnewCanvas :: !Pos !f  !JapiState -> (!Canvas, !*JapiState)
	
instance NewCanvas Container 
instance NewCanvas Framer 



class SetVal f g
where
   jsetval :: !f !g !JapiState -> (!f, !*JapiState)

instance SetVal Scroll Real
instance SetVal Device Int
instance SetVal TDev Int



class DeviceSeting f where
    jnew7seg:: !Pos !Int !Int !f !JapiState -> (!Device, !*JapiState)
    jnewHScrollBar:: !Pos !Real !Real
                !f !JapiState -> (!Scroll, !*JapiState)
    jnewVScrollBar:: !Pos !Real !Real
                !f !JapiState -> (!Scroll, !*JapiState)

instance DeviceSeting Framer
instance DeviceSeting Container

class Dispose f where
    jdispose :: !f !JapiState -> *JapiState
    
instance Dispose Canvas
instance Dispose RC

class Print f where
    jprint :: !f  -> f
    
instance Print Canvas 
instance Print RC


class SetColor f where
   bg_color ::  !(!Int, !Int, !Int) !f -> f
   color ::  !(!Int, !Int, !Int) !f -> f
   bg_namedcolor :: !Int !( !f, !JapiState) -> (!f, !*JapiState)
      
instance SetColor TDev
instance SetColor Framer
instance SetColor Container
instance SetColor Canvas
instance SetColor RC


class Layout f where
	hGap :: !f !Int !JapiState -> (!f, !*JapiState)
	vGap :: !f !Int !JapiState -> (!f, !*JapiState)
	jhorizontalLayout :: !f !JapiState -> (!f, !*JapiState)
	jverticalLayout :: !f !JapiState -> (!f, !*JapiState)

instance Layout Container
instance Layout Framer



class SetText f
where
   jsetText :: !f !String -> f   

instance SetText TDev
instance SetText Device



class GetText f
where
   jgetText :: !f  -> String
   
instance GetText TDev
instance GetText Device



class Action g
where
   act :: !g -> Int

instance Action Scroll
instance Action Container
instance Action Device
instance Action Framer
instance Action TDev
instance Action Entry
instance Action LDev



class SetPos f
where
   jsetxy :: !f !Int !Int !JapiState -> (!f, !*JapiState)
   jsetwh :: !f !Int !Int !JapiState -> (!f, !*JapiState)
   setxy :: !f (!Int, !Int) !JapiState -> (!f, !*JapiState)
   
instance SetPos TDev
instance SetPos Container
instance SetPos Framer
instance SetPos Device 
instance SetPos LDev
instance SetPos Canvas



class Sound f where
   jplaysound :: !f !String !JapiState -> (!f, !*JapiState)
   
instance Sound Device 
instance Sound TDev 
instance Sound Container 
instance Sound Framer 



class Packing f where
   jpack :: !f !JapiState -> (!f, !*JapiState)

instance Packing Container
instance Packing Framer



class SetFont f
where
   jsetfont :: !Font !f  -> f

instance SetFont TDev
instance SetFont Framer
instance SetFont Container
instance SetFont Canvas
instance SetFont LDev


class NewTDev f where
   jnewLabel :: !Pos !String !f   !*JapiState -> (!TDev, !*JapiState)          
   jnewTextArea::  !Pos !Int !Int !f  !*JapiState -> (!TDev, !*JapiState)
   jnewPanel ::  !Pos !f !*JapiState -> (!Container, !*JapiState)   
   jnewButton :: !Pos !String !f !JapiState -> (!TDev, !*JapiState)
   jnewCheckBox :: !Pos !String !f !JapiState -> (!TDev, !*JapiState)
   jnewField :: !Pos !Int !f !JapiState -> (!TDev, !*JapiState)
      
instance NewTDev Container
instance NewTDev Framer


// Handling JapiState
begin_japi :: !*World -> (!JapiState,!*World)
end_japi :: !JapiState !*World -> *World
sync_japi :: !JapiState !*World -> (!JapiState,!*World)
jquit :: !JapiState -> JapiState


// Reading user's actions (events).
// jnextaction waits for an event, 
// while jgetaction does not wait, 
// if an action is unavailable.
jnextaction ::  !JapiState -> (!Int, !*JapiState)
jgetaction :: !Int !JapiState -> (!Int, !*JapiState)

// jkeycode roduces the pressed keycode;
// its argument must be a keyboard device.
jkeycode :: !Device -> *Int

// jsleep pouses the computation for a given time.
jsleep :: !Int !JapiState -> (!Int,!JapiState)


// Mouse handling functions

jmousereleased :: !Canvas -> (!Device, !Canvas)
jmousepressed :: !Canvas -> (!Device, !Canvas)
mx :: !Device -> Int
my :: !Device -> Int
mxy :: !Device -> (Int, Int)

// Drawables

red :: (Int, Int, Int)  
white :: (Int, Int, Int)
blue :: (Int, Int, Int)
green :: (Int, Int, Int)
yellow :: (Int, Int, Int)
black :: (Int, Int, Int)

jloadimage :: !String !JapiState -> (!Int,!JapiState)
//jgetimage :: !Canvas -> Int

jsavebmp :: !Int !String !JapiState -> (!Int, !JapiState)
jsaveppm :: !Int !String !JapiState -> (!Int, !JapiState)
jsavejpg :: !Int !String !JapiState -> (!Int, !JapiState)

jfilesel :: !Framer !String !JapiState -> (!String,!*JapiState)

jprinter :: !Framer !JapiState -> (!Canvas, !*JapiState)
//jprint :: !Canvas  -> Canvas
//jdispose :: !Canvas !JapiState -> *JapiState


// Drawing functions
jdraw :: !Drawable !Canvas -> Canvas
//draw :: ![Drawable] !Canvas -> Canvas
jfill :: !Drawable !Canvas -> Canvas
//fill :: ![Drawable] !Canvas -> Canvas
jdrawpix ::  !(!Int, !Int) !Canvas -> Canvas
jfillc :: !(!Int, !Int, !Int)  !Drawable !Canvas -> Canvas
jdrawc :: !(!Int, !Int, !Int)  !Drawable !Canvas -> Canvas

jfilltriangle :: !(!Int, !Int) !(!Int, !Int) !(!Int, !Int)
                 !Canvas   -> Canvas

// Containers
jhide :: !Container !JapiState -> (!Container,!JapiState)  
show :: !Container -> Container
hide :: !Container -> Container

jEnable :: !Framer !JapiState -> (!Framer, !JapiState) 
jDisable :: !Framer !JapiState -> (!Framer, !JapiState)
jcliprect :: !Canvas !Int !Int !Int !Int !JapiState-> (!Canvas, !JapiState)


// A random number generator. Useful in games.
jrandom :: !Int !JapiState -> (!Int, !*JapiState)


// Setting device properties
jsetstate :: !TDev !Int !JapiState -> (!TDev, !*JapiState)
jsetpos :: !Device !Int !Int !JapiState -> (!Device, !*JapiState)
jsetsize :: !Device !Int !Int !JapiState -> (!Device, !*JapiState)
jsetmin :: !TDev !Int !JapiState -> (!TDev, !*JapiState)
jsetmax :: !TDev !Int !JapiState -> (!TDev, !*JapiState)
jsetdanger :: !TDev !Int !JapiState -> (!TDev, !*JapiState)
jseticon :: !Framer !Int !JapiState -> (!Framer, !*JapiState)

jselect ::  !Int !LDev -> LDev
jdeselect ::  !Int !LDev -> LDev

jsetcolumns :: !TDev !Int !JapiState -> (!TDev, !*JapiState)
jsetrows :: !TDev !Int !JapiState -> (!TDev, !*JapiState)

class SetCursor f where
   jsetcursor ::  !Int !f !JapiState -> (!f, !*JapiState)
      
instance SetCursor Framer
instance SetCursor Container


// Getting device properties
jgetselect :: !LDev  -> (!Int, !LDev)
jgetwidth :: !Canvas  -> (!Int, !Canvas)
jgetheight :: !Canvas  -> (!Int, !Canvas)
jgetstate :: !TDev  !JapiState -> (!Bool, !*JapiState)
jslideval :: !Scroll -> (!Real, !Scroll)
imagewidth :: !Int !JapiState -> (!Int, !JapiState)
imageheight :: !Int !JapiState -> (!Int, !JapiState)
imagesize :: !Int !JapiState -> (!Int, !Int, !JapiState)

// Creating new devices
jnewFrame :: !Pos !String !JapiState -> (!Framer, !*JapiState)
jnewMeter :: !Pos !String !Container !*JapiState -> (!TDev, !*JapiState)
jnewMenu :: !String !Bar !*JapiState -> (!Menu,  !*JapiState)
jnewItem :: !String !Menu !*JapiState -> (!Entry,  !*JapiState)
jnewBar :: !Framer !*JapiState -> (!Bar, !*JapiState)
jnewDialog ::  !Pos !String !Framer !*JapiState -> (!Container, !*JapiState)
jnewWindow :: !Framer !JapiState -> (!Container, !*JapiState)

jnewPopup :: !String !Framer !*JapiState -> (!Menu,  !*JapiState)
jshowpopup ::  (!Int, !Int) !Menu !JapiState -> (!Menu, !*JapiState)


// Extending Clean for Cartesian Coordinates 
instance + (a, b) | PlusMin a & PlusMin b
instance - (a, b) | PlusMin a & PlusMin b
instance + (Int,Int, Int)

apply :: !(Canvas -> Canvas) !(!Canvas, !JapiState) -> (!Canvas, !JapiState)

// Cartesian drawing
mks :: !Canvas !(!Real, !Real) !(Real, Real) -> RC
gCanvas :: !RC -> Canvas
rdraw :: !CFig !RC -> RC
rmxy :: !Device !RC -> (!(!Real, !Real), !RC)

class Draw f g where
   draw :: ![f] !g -> g	
   fill :: ![f] !g -> g
   
instance Draw Drawable Canvas 
instance Draw CFig RC

(@) infix  9 :: !(a, a) Projection -> a


jsync :: !JapiState -> *JapiState

jsound :: !String -> Int
